#include "sphere_of_cubes.h"

#include <gl/glfw.h>
#include <glm/glm.hpp>

SphereOfCubes::SphereOfCubes()
{


	int dim1 = 7;
	int dim2 = 7;

	int faceIdx = 0;
	for(int side=0; side<6; side++)
	{
		for(int i=0; i<dim1; i++)
		{
			for(int j=0; j<dim2; j++)
			{
				float s = float(i)/(dim1-1);
				float t = float(j)/(dim2-1);
				glm::vec3 &pointOnCube = cube(side,s,t);
				glm::vec3 pos = normalize( pointOnCube );
				glm::vec3 normalDir = pos;
				pointsOnSphere.push_back( pos );
				// Same color as normal, except translated
				glm::vec3 cubeColor = 0.5f + pos*0.5f;
				colors.push_back( cubeColor );

				// Create a z-extrude param for each cube
				faceMorphPositions.push_back( 1.0f );

				// Create orientation matrix

				glm::vec3 forward = normalDir;
				//Vec3f upward( 0.0f, 1.0f, 0.0f );
				Vec3f upward( forward[2], forward[0], forward[1] ); // Using forward vector with numbers swapped inorder to avoid 
				Vec3f right = normalize( forward.cross(upward) );
				upward = normalize( right.cross(forward) );

				glm::mat4 mtx( 
					glm::vec3( right[0], right[1], right[2], 0.0f), 
					glm::vec3( upward[0], upward[1], upward[2], 0.0f), 
					glm::vec3( forward[0], forward[1], forward[2], 0.0f), 
					glm::vec3( 0.0f, 0.0f, 0.0f, 1.0f) 
					);

				

				frames.push_back( mtx );

			} // for j
		} // for i 
	} // for s 

}


// side = front,back,left,right,top,bottom
glm::vec3 SphereOfCubes::cube(int side,float s, float t){
	switch(side){
	case 0: 
		return glm::vec3(1.f-2*s,1.f-2.f*t,+1.f);
	case 1:
		return glm::vec3(1.f-2*s,1.f-2.f*t,-1.f);
	case 2:
		return glm::vec3(-1.f,1.f-2.f*s,1.f-2.f*t);
	case 3:
		return glm::vec3(+1.f,1.f-2.f*s,1.f-2.f*t);
	case 4:
		return glm::vec3(+1.f-2*s,1.f,1.f-2.f*t);
	case 5:
		return glm::vec3(+1.f-2*s,-1.f,1.f-2.f*t);
	}
}



void SphereOfCubes::draw()
{
	//glDisable(GL_LIGHTING);
	glEnable(GL_COLOR_MATERIAL);

	for(size_t i=0; i<pointsOnSphere.size(); i++)
	{
		glPushMatrix();{

		Vec3f &pos = pointsOnSphere[i]; 
		
		glColor3fv( & (colors[i])[0] );
		glTranslatef( pos[0], pos[1], pos[2] );
		glMultMatrixf( &(frames[i])[0] );
		
		glScalef(1,1,faceMorphPositions[i]);
		
		throw char "not implemented";
		//Shapes3D::DrawCube(.05f);
		
		}glPopMatrix();
	}

}

int SphereOfCubes::getFaceCount()
{
	return pointsOnSphere.size();
}

void SphereOfCubes::setMorphPos( int faceIdx, float t )
{
	faceMorphPositions[faceIdx] = t;
}

Vec3f SphereOfCubes::getVertexColor( int idx )
{
	return colors[idx];
}
